#include "Common.hpp"
#include "InetAddr.hpp"
#include <sys/select.h>
#include <unistd.h>

// ./tcpclient ip port
int main(int argc, char *argv[])
{
	if (argc != 3)
	{
		std::cerr << "Usage: ./tcpclient ip port" << std::endl;
		exit(USAGE_ERR);
	}

	std::string ip = argv[1];
	uint16_t port = std::stoi(argv[2]);

	// 创建客户端套接字
	int clientfd = socket(AF_INET, SOCK_STREAM, 0);
	if (clientfd < 0)
	{
		std::cerr << "socket error" << std::endl;
		exit(SOCKET_ERR);
	}

	InetAddr server(ip, port);
	int n = connect(clientfd, server.GetAddrPtr(), server.AddrLen());
	if (n < 0)
	{
		std::cerr << "connect error" << std::endl;
		exit(CONNECT_ERR);
	}

	fd_set read_fds;
	char buffer[1024];

	while (true)
	{
		FD_ZERO(&read_fds);
		FD_SET(STDIN_FILENO, &read_fds);
		FD_SET(clientfd, &read_fds);

		std::cout << "Please input #" << std::flush;

		int activity = select(clientfd + 1, &read_fds, nullptr, nullptr, nullptr);
		if ((activity < 0) && (errno != EINTR))
		{
			LOG(LogLevel::ERROR) << "select error";
			break;
		}

		// 检查是不是套接字clientfd有活动
		if (FD_ISSET(clientfd, &read_fds))
		{
			// 接收数据
			int size = read(clientfd, buffer, sizeof(buffer) - 1);
			if (size > 0)
			{
				buffer[size] = 0;
				std::string echo = "server echo# ";
				echo += std::string(buffer);
				std::cout << echo << std::endl;
			}
			else if (size == 0)
			{
				LOG(LogLevel::INFO) << "服务器已关闭";
				close(clientfd);
				LOG(LogLevel::INFO) << "用户退出客户端";
				exit(SUCESS);
			}
			else
			{
				LOG(LogLevel::ERROR) << "服务器异常退出，用户被迫下线";
				close(clientfd);
				exit(SOCKET_ERR);
			}
		}

		// 检查是不是标准输入有活动
		if(FD_ISSET(STDIN_FILENO, &read_fds)){
			std::string line;
			if(!std::getline(std::cin, line)){
				LOG(LogLevel::INFO) << "用户退出客户端";
				break;
			}

			write(clientfd, line.c_str(), line.size());
		}

		
	}

	return 0;
}